#include"include/Task.h"
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <sys/socket.h>


// 客户端初始化命令
task_t* task_init(int netfd){
    task_t *task=(task_t *)malloc(sizeof(task_t));
    ERROR_CHECK(task,NULL,"fail in task_init");
    task->_netfd=netfd;
    task->_train._cmdType=CMD_TYPE_INIT;
    task->_train._trainLen=0;
    
     memset(task->_dir, 0, sizeof(task->_dir)); // 使用整个数组的大小
     memset(task->_train._data, 0, sizeof(task->_train._data));

    return task;
}

// 客户端建立与服务器的连接
int InitTcpconnect(char *ip,char *port){

    int sockfd=socket(AF_INET, SOCK_STREAM, 0);
    ERROR_CHECK(sockfd, -1, "fail in client makesocket");
    struct sockaddr_in addr;
    addr.sin_family=AF_INET;
    addr.sin_port=htons(atoi(port) );
    addr.sin_addr.s_addr=inet_addr(ip);
    int ret_connect=connect(sockfd, (struct sockaddr*)&addr, sizeof(addr));
    ERROR_CHECK(ret_connect, -1, "fail in client connect");
    return sockfd;
}

int EpollAdd(int epfd,int fd){
     // 将监听sockfd加入监听
    struct epoll_event event;
    event.events=EPOLLIN;
    event.data.fd=fd;
    epoll_ctl(epfd,EPOLL_CTL_ADD,fd,&event);
    return 0;
}
int EpollDel(int epfd,int fd){
   //删除fd的监听 
    epoll_ctl(epfd,EPOLL_CTL_DEL,fd,NULL);
    return 0;
}
//初始化连接结构体
int init_accept_info(accept_info_t * info){
    memset(info->username,0,sizeof(info->username));
    info->is_new=0;
    memset(info->jwt,0,sizeof(info->jwt));
    info->jwt_length=0;
    //初始化jwt结构体
    return 0;
}

// 将字符串切分并存入tokens数组中
void splitString(char *stdinchar,const char *delimiter,char *tokens[]){
     char *saveptr=NULL;
     char *token=strtok_r(stdinchar,delimiter,&saveptr);
     int i=0;
     while(token!=NULL){
        tokens[i++]=token;
        token=strtok_r(NULL,delimiter,&saveptr);
     }
     tokens[i]=NULL;
}
// 将切分好的字符串数组解析并存入task中
void parseCommand(char *tokens, task_t *task) {
    char *temp[1024] = {0};
    
    // 复制标准输入
    char *input_copy = strdup(tokens);
    if(input_copy == NULL) return;

    // 分割标准输入
    splitString(input_copy, " ", temp);
    
    // 将命令存入task中 
    task->_train._cmdType = getcmdType(temp[0]);
    task->_train._trainLen = 0;
    // 初始化数据区
    memset(task->_train._data, 0, sizeof(task->_train._data));
    
    // 清理旧的目录数据（防止内存泄漏）
    for(int i = 0; i < 1024 && task->_dir[i] != NULL; i++) {
        free(task->_dir[i]);
        task->_dir[i] = NULL;
    }
   
    // 检查是否有参数
    if(temp[1] != NULL) {
        // 将temp[1]按照/分割并存入task->_dir中
        char *dirs[1024] = {0};
        char *dircopy = strdup(temp[1]);
        if(dircopy) {
            splitString(dircopy, "/", dirs);
            int index = 0;
            for(int i = 0; dirs[i] != NULL && index < 1023; i++) {
                // 跳过空串
                if(strlen(dirs[i]) == 0) continue;
                task->_dir[index++] = strdup(dirs[i]);
                // 存储斜杠
                if(dirs[i+1] != NULL && index < 1023) {
                    task->_dir[index++] = strdup("/");
                }
            }
            free(dircopy);
        }
        
        // 合并所有输入的参数
        for(int i = 1; temp[i] != NULL; i++) {
            strncat(task->_train._data, temp[i], sizeof(task->_train._data) - strlen(task->_train._data) - 1);
            if(temp[i+1] != NULL) {
                strncat(task->_train._data, " ", sizeof(task->_train._data) - strlen(task->_train._data) - 1);
            }
        }
        task->_train._trainLen = strlen(task->_train._data);
    } else {
        // 没有参数的情况
        task->_train._trainLen = 0;
    }
    
    for(int i = 0; task->_dir[i] != NULL; i++) {
        printf("task->_dir[%d]:%s\n", i, task->_dir[i]);
    }
    
    free(input_copy);
    return;
}

CmdType getcmdType(char *cmd){
   // 从标准输入中获取命令的类型
   if(strcmp(cmd, "cd")==0){
        return CMD_TYPE_CD;
   }
   else if(strcmp(cmd, "ls")==0){
        return CMD_TYPE_LS;
   }
   else if (strcmp(cmd, "pwd")==0) {
        return CMD_TYPE_PWD;
   }
   else if(strcmp(cmd, "puts")==0){
        return CMD_TYPE_PUTS;
   }
   else if(strcmp(cmd, "gets")==0){
        return  CMD_TYPE_GETS;
   }
   else if(strcmp(cmd, "remove")==0){
        return CMD_TYPE_REMOVE;
   }
   else if(strcmp(cmd, "mkdir")==0){
        return CMD_TYPE_MKDIR;
   }
   else if(strcmp(cmd, "rmdir")==0){
        return CMD_TYPE_RMDIR;
   }
   else if(strcmp(cmd, "quit")==0){
        return CMD_TYPE_QUIT;
   }
   else if(strcmp(cmd, "help")==0){
        return CMD_TYPE_HELP;
   }
      return CMD_TYPE_NOTCMD;
   }

int handle_pwd(task_t *task){
    printf("客户端路径:%s\n",task->_train._data);
    return 0;
}
int handle_ls(task_t *task){
    printf("客户端执行ls命令\n");
    // 确保_data是字符串
    task->_train._data[task->_train._trainLen] = '\0';
    printf("%s\n", task->_train._data);
    return 0;
}

// 辅助函数：接收/发送指定长度数据
int recv_n(int sockfd, void *buf, int len) {
    int total = 0, ret;
    char *p = (char*)buf;
    while(total < len) {
        ret = recv(sockfd, p + total, len - total, 0);
        if(ret <= 0) return ret;
        total += ret;
    }
    return total;
}
int send_n(int sockfd, void *buf, int len) {
    int total = 0, ret;
    char *p = (char*)buf;
    while(total < len) {
        ret = send(sockfd, p + total, len - total, 0);
        if(ret <= 0) return ret;
        total += ret;
    }
    return total;
}

// 客户端与服务器建立临时连接
int temp_connect(char *ip,char *port,accept_info_t *info){
    //建立临时连接
    int sockfd = InitTcpconnect(ip,port);
    printf("temp sockfd:%d\n",sockfd);
    //发送用户信心
    info->is_new = 1;
    send(sockfd,info,sizeof(accept_info_t),0);
    int flag = 0;
    recv(sockfd,&flag,sizeof(int),0);
    if(flag == -1){
        printf("用户身份验证失败\n");
        close(sockfd);
        return -1;
    }
    return sockfd;
}

void *handle_puts(void *arg){
    task_t *task = (task_t*)arg;
    printf("客户端执行puts命令\n");
}

// int handle_puts(task_t *task){
//     printf("客户端执行puts命令\n");
//     // 假设 task->_train._data 里存的是文件名
//     int fd=open(task->_train._data,O_RDONLY);
//     if(fd==-1){
//         printf("打开文件失败\n");
//         return -1;
//     }
//     //发送文件大小
//     off_t fileSize=lseek(fd,0,SEEK_END);
//     send_n(task->_netfd,&fileSize,sizeof(off_t));
//     lseek(fd,0,SEEK_SET);
//     //定义发送标志位
//     bool flag=flag=(fileSize>MAX_FILE_SIZE)?true:false;
//     if(flag==true){
//         //大文件发送
//        off_t sended=fileSize;
//        char *buf=malloc(BLOCK_SIZE);
//        ERROR_CHECK(buf,NULL,"客户端大文件分配内存失败");
//        while(sended>0){
//         off_t to_send=sended>BLOCK_SIZE?BLOCK_SIZE:sended;
//         int ret=read(fd,buf,to_send);
//         ERROR_CHECK(ret,0,"客户端大文件读取失败");
//         send_n(task->_netfd,buf,to_send);
//         sended-=to_send;
//        }
//        free(buf);
//     }
//     else{
//     while(1){
//         //使用小火车传输
//         bzero(task->_train._data,sizeof(task->_train._data));
//         int dataLen = read(fd, task->_train._data, sizeof(task->_train._data));
//         if(dataLen == 0){
//         //发送空包给服务器
//         send_n(task->_netfd, &dataLen, sizeof(int));
//             break;
//         }
//         send_n(task->_netfd, &dataLen, sizeof(int));
//         send_n(task->_netfd, task->_train._data, dataLen);
//     }
//         }
//     close(fd);
//     return 0;
// }
// int handle_gets(task_t *task){
//     printf("客户端执行gets命令\n");
//     int fd = open(task->_train._data, O_WRONLY|O_CREAT|O_TRUNC, 0666);
//     if(fd == -1){
//         printf("打开文件失败\n");
//         return -1;
//     }
//     // 接收文件内容
//     while(1){
//         printf("--------------------------------\n");
//         int dataLen = 0;
//         recv_n(task->_netfd, &dataLen, sizeof(int));
//         printf("接收下载文件的长度:%d\n",dataLen);
//         if(dataLen == 0) break;
//         recv_n(task->_netfd, task->_train._data, dataLen);
//         write(fd, task->_train._data, dataLen);
//     }
//     close(fd);
//     return 0;
// }







